home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / winftp.zip / WNFTPSRC.ZIP / WS_CHILD.C < prev    next >
C/C++ Source or Header  |  1994-01-11  |  29KB  |  795 lines

  1. /***************************************************************************
  2.   Windows Sockets FTP Client Application Support Module
  3.  
  4.   Written by:
  5.      Santanu Lahiri              Internet: slahiri@magnus.acs.ohio-state.edu
  6.  
  7. Converted the Create Buttons calls to simulated buttons.  Added necessary
  8. WM_PAINT code to handle displaying the buttons in the appropriate mode
  9.  
  10. Added the ComboBox "History" feature.
  11.  
  12. Cleaned up WM_PAINT code that was eating resources - Deselected created
  13. brushes and pens before the hdc was released.
  14.  
  15. *****************************************************************************/
  16. /*
  17.   MODULE: WS_CHILD.C  (child window functions)
  18. */
  19.  
  20. #include "ws_glob.h"
  21. #include "winftp.H"
  22. #include <dos.h>
  23. #include <ctype.h>
  24.  
  25. #define WS_CHILDSTYLE  WS_CHILD|WS_VISIBLE
  26. #define LBS_STYLE      LBS_STANDARD|WS_VSCROLL|WS_CHILDSTYLE|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT
  27. #define WS_TXTSTYLE    WS_CHILDSTYLE|SS_LEFTNOWORDWRAP
  28. #define WS_RADIOSTYLE  WS_CHILDSTYLE|BS_RADIOBUTTON
  29. #define CBS_STYLE      WS_CHILDSTYLE|WS_VSCROLL|CBS_DROPDOWNLIST|CBS_HASSTRINGS|CBS_SORT
  30. #define SBV_STYLE      WS_CHILDSTYLE|SBS_VERT|WS_VISIBLE
  31. #define EDT_STYLE      WS_CHILDSTYLE|WS_BORDER|ES_AUTOHSCROLL
  32.  
  33. #define XSIZ(x) (x*nWndx)/4
  34. #define YSIZ(x) (x*nWndy)/8
  35.  
  36. #ifdef WIN32
  37.    #define MAXLINES 150
  38. #else
  39.    #define MAXLINES 100
  40. #endif
  41.  
  42. #define STATLEN  151
  43.  
  44. char *lpStatusLines=NULL;
  45. int nStatusPtr=0;
  46. int nStatusScroll=1;
  47.  
  48. RECT rcMsg;
  49.  
  50. BOOL bCanMKD,bCanRMD,bCanREN,bCanDELE,bIsQVT,bIsNCSA,bIs5000,bIsDual;
  51. BOOL bHELP=FALSE;
  52.  
  53. LPSTR lpListBox = "listbox";
  54. LPSTR lpButton  = "button";
  55. LPSTR lpStatic  = "static";
  56. LPSTR lpEdit    = "edit";
  57. LPSTR lpComboBox= "combobox";
  58. LPSTR lpScroll  = "scrollbar";
  59. LPSTR lpChgDir  = "ChgDir";
  60. LPSTR lpMkDir   = "MkDir";
  61. LPSTR lpRmDir   = "RmDir";
  62. LPSTR lpRefresh = "Refresh";
  63. LPSTR lpDisplay = "Display";
  64. LPSTR lpRename  = "Rename";
  65. LPSTR lpDelete  = "Delete";
  66. LPSTR lpConnect = "Connect";
  67. LPSTR lpClose   = "Close";
  68. LPSTR lpLongDir = "LongDir";
  69. LPSTR lpAbort   = "Abort";
  70. LPSTR lpOptions = "Options";
  71. LPSTR lpAbout   = "About";
  72. LPSTR lpExit    = "Exit";
  73. LPSTR lpToRemote= "-->";
  74. LPSTR lpToLocal = "<--";
  75.  
  76. typedef struct
  77. {
  78.   LPSTR *lpBtnTxt;
  79.   RECT rcBtn;
  80.   int nBtnID, nStat;
  81.   int nTxtx, nTxty;
  82.   int nSendMsg;
  83.   RECT rcExt;
  84. } BTNPOS;
  85.  
  86. static RECT rcLEdt, rcREdt, rcLLst, rcRLst, rcLDir, rcLFile, rcRDir, rcRFile;
  87.  
  88. #define  BUTTONS   23
  89.  
  90. BOOL bEnabled[BUTTONS];
  91.  
  92. BTNPOS bpButton[BUTTONS] = 
  93. {  
  94.   &lpChgDir,  {  84,  32, 26, 13}, BTN_LCHANGE,         0, 0, 0, 0, {0, 0, 0, 0},
  95.   &lpMkDir,   {  84,  46, 26, 13}, BTN_LMKDIR,          0, 0, 0, 0, {0, 0, 0, 0},
  96.   &lpRmDir,   {  84,  60, 26, 13}, BTN_LRMDIR,          0, 0, 0, 0, {0, 0, 0, 0},
  97.   &lpRefresh, {  84,  84, 26, 13}, BTN_LREFRESH,        0, 0, 0, 0, {0, 0, 0, 0},
  98.   &lpDisplay, {  84, 107, 26, 13}, BTN_LDISPLAY,        0, 0, 0, 0, {0, 0, 0, 0},
  99.   &lpRename,  {  84, 121, 26, 13}, BTN_LRENAME,         0, 0, 0, 0, {0, 0, 0, 0},
  100.   &lpDelete,  {  84, 135, 26, 13}, BTN_LDELETE,         0, 0, 0, 0, {0, 0, 0, 0},
  101.   &lpChgDir,  { 213,  32, 26, 13}, BTN_RCHANGE,         0, 0, 0, 0, {0, 0, 0, 0},
  102.   &lpMkDir,   { 213,  46, 26, 13}, BTN_RMKDIR,          0, 0, 0, 0, {0, 0, 0, 0},
  103.   &lpRmDir,   { 213,  60, 26, 13}, BTN_RRMDIR,          0, 0, 0, 0, {0, 0, 0, 0},
  104.   &lpRefresh, { 213,  84, 26, 13}, BTN_RREFRESH,        0, 0, 0, 0, {0, 0, 0, 0},
  105.   &lpDisplay, { 213, 107, 26, 13}, BTN_RDISPLAY,        0, 0, 0, 0, {0, 0, 0, 0},
  106.   &lpRename,  { 213, 121, 26, 13}, BTN_RRENAME,         0, 0, 0, 0, {0, 0, 0, 0},
  107.   &lpDelete,  { 213, 135, 26, 13}, BTN_RDELETE,         0, 0, 0, 0, {0, 0, 0, 0},
  108.   &lpToLocal, { 116, 101, 14, 13}, BTN_REMOTE_TO_LOCAL, 0, 0, 0, 0, {0, 0, 0, 0},
  109.   &lpToRemote,{ 116, 118, 14, 13}, BTN_LOCAL_TO_REMOTE, 0, 0, 0, 0, {0, 0, 0, 0},
  110.   &lpConnect, {   4, 185, 32,  9}, BTN_CONNECT,         0, 0, 0, 0, {0, 0, 0, 0},
  111.   &lpClose,   {  38, 185, 32,  9}, BTN_CLOSE,           0, 0, 0, 0, {0, 0, 0, 0},
  112.   &lpLongDir, {  72, 185, 32,  9}, BTN_LONG,            0, 0, 0, 0, {0, 0, 0, 0},
  113.   &lpAbort,   { 106, 185, 34,  9}, BTN_ABORT,           0, 0, 0, 1, {0, 0, 0, 0},
  114.   &lpOptions, { 142, 185, 32,  9}, BTN_OPTION,          0, 0, 0, 0, {0, 0, 0, 0},
  115.   &lpAbout,   { 176, 185, 32,  9}, BTN_ABOUT,           0, 0, 0, 0, {0, 0, 0, 0},
  116.   &lpExit,    { 210, 185, 32,  9}, BTN_EXIT,            0, 0, 0, 0, {0, 0, 0, 0} 
  117. };
  118.  
  119. //*********************************************************************
  120. //  Create the Button positions array.  Compute the actual screen sizes
  121. //  and the screen text positions based on the initial button position
  122. //  and size.  Use the actual screen size of text to locate it in a button.
  123. //*********************************************************************
  124. void CreateButtonPos (HWND hWnd)
  125. {
  126.   HDC hdc;
  127.   DWORD dwExt;
  128.   RECT rc;
  129.   int nI, cExt, cHt;
  130.  
  131. #ifdef WIN32
  132.   SIZE sizeStr;
  133. #endif
  134.   
  135.   hdc = GetDC (hWnd);
  136.   SelectObject (hdc, GetStockObject (ANSI_VAR_FONT));   //  This allows actual size calc.
  137.  
  138.   for (nI=0; nI<sizeof (bpButton)/sizeof (BTNPOS); nI++)
  139.   {
  140.     bEnabled[nI] = TRUE;
  141.  
  142. #ifdef WIN32
  143.     dwExt = GetTextExtentPoint (hdc, *bpButton[nI].lpBtnTxt, lstrlen (*bpButton[nI].lpBtnTxt), &sizeStr);
  144.     cExt = sizeStr.cx;                 //  Length of screen text
  145.     cHt  = sizeStr.cy;                 //  Height of screen text
  146. #else
  147.     dwExt = GetTextExtent (hdc, *bpButton[nI].lpBtnTxt, lstrlen (*bpButton[nI].lpBtnTxt));
  148.     cExt = LOWORD (dwExt);                 //  Length of screen text
  149.     cHt  = HIWORD (dwExt);                 //  Height of screen text
  150. #endif
  151.     
  152.     rc = bpButton[nI].rcExt = bpButton[nI].rcBtn;  //  Copy button size for later use
  153.     rc.right += rc.left;                   //  Compute screen right bound
  154.     rc.bottom+= rc.top;                    //  Compute screen lower bound
  155.     rc.left   = (rc.left   * nWndx) / 4;   //  Convert to MM_TEXT pixel count
  156.     rc.top    = (rc.top    * nWndy) / 8;
  157.     rc.right  = (rc.right  * nWndx) / 4;
  158.     rc.bottom = (rc.bottom * nWndy) / 8;
  159.     bpButton[nI].rcBtn = rc;               //  Save the computed sizes.
  160.     bpButton[nI].nTxtx = (rc.left+rc.right-cExt)/2;  //  Compute the text position
  161.     bpButton[nI].nTxty = (rc.top+rc.bottom-cHt)/2;   //  horizontal and vertical both.
  162.   }
  163.   
  164.   rcMsg.top    = YSIZ (164);
  165.   rcMsg.bottom = YSIZ (179);
  166.   rcMsg.left   = XSIZ (8);
  167.   rcMsg.right  = XSIZ (228);
  168.   
  169.   ReleaseDC (hWnd, hdc);    //  Done here, release resources.
  170. }
  171.  
  172. //*********************************************************************
  173. //*********************************************************************
  174. void CreateListRectPos (LPRECT rcLDir, int nX, int nY, int nExt, int nH)
  175. {
  176.   rcLDir->left  = nX;
  177.   rcLDir->top   = nY;
  178.   rcLDir->right = nX+nExt-1;
  179.   rcLDir->bottom= nY+nH-1;
  180. }
  181.  
  182. //*********************************************************************
  183. //*********************************************************************
  184. int GetChildWindowID (LPARAM lParam)
  185. {
  186.   POINT pt;
  187.   BOOL bFlag = (pt.y > rcLLst.bottom);
  188.  
  189.   pt.y = HIWORD (lParam);
  190.   pt.x = LOWORD (lParam);
  191.   if (PtInRect (&rcLFile, pt)) return LST_LFILES;
  192.   if (PtInRect (&rcRFile, pt)) return LST_RFILES;
  193.   if (PtInRect (&rcLDir, pt)) return LST_LDIRS;
  194.   if (PtInRect (&rcRDir, pt)) return LST_RDIRS;
  195.   if (PtInRect (&rcLLst, pt)) return LST_LDIRLST;
  196.   if (PtInRect (&rcRLst, pt)) return LST_RDIRLST;
  197.   if (PtInRect (&rcLEdt, pt)) return EDT_LFILETYPE;
  198.   if (PtInRect (&rcREdt, pt)) return EDT_RFILETYPE;
  199.   
  200.   return 0;
  201. }
  202.  
  203. //*********************************************************************
  204. //*********************************************************************
  205. int CreateSubWindows(HWND hParent,HWND hInst)
  206. {
  207.   HFONT hFont = GetStockObject (ANSI_VAR_FONT);
  208.   int nX1, nX2, nY1, nY2, nH1, nH2, nExt;
  209.  
  210.   CreateButtonPos (hParent);  //  Create the button screen positions.
  211.   
  212.   nExt= XSIZ ( 28);           //  Editbox Extent
  213.   nX1 = XSIZ ( 81);           //  Local File Type position
  214.   nX2 = XSIZ (210);           //  Remote File Type position
  215.   nY1 = YSIZ (  6);           //  EditBox Y position
  216.   nH1 = YSIZ ( 10);           //  EditBox height
  217.  
  218.   CreateWindow (lpEdit, NULL, EDT_STYLE,
  219.     nX1, nY1, nExt, nH1, hParent, (HMENU) EDT_LFILETYPE, hInst,  NULL);
  220.   
  221.   CreateWindow (lpEdit, NULL, EDT_STYLE,
  222.     nX2, nY1, nExt, nH1, hParent, (HMENU) EDT_RFILETYPE, hInst,  NULL);
  223.  
  224.   CreateListRectPos (&rcLEdt,  nX1, nY1, nExt, nH1);
  225.   CreateListRectPos (&rcREdt,  nX2, nY1, nExt, nH1);
  226.  
  227.   nExt= XSIZ (74);            //  Combo box Extent
  228.   nX1 = XSIZ ( 7);            //  Local Dir List position
  229.   nX2 = XSIZ (136);           //  Remote Dir List position
  230.   nY1 = YSIZ (32);            //  Combo Box Y position
  231.   nH1 = YSIZ (82);            //  Combo Box height when opened
  232.  
  233.   hLbxLDirLst = CreateWindow (lpComboBox, NULL, CBS_STYLE,
  234.     nX1, nY1, nExt, nH1, hParent, (HMENU) LST_LDIRLST, hInst,  NULL);
  235.   
  236.   hLbxRDirLst = CreateWindow (lpComboBox, NULL, CBS_STYLE,
  237.     nX2, nY1, nExt, nH1, hParent, (HMENU) LST_RDIRLST, hInst,  NULL);
  238.     
  239.   CreateListRectPos (&rcLLst,  nX1, nY1, nExt, nH1);
  240.   CreateListRectPos (&rcRLst,  nX2, nY1, nExt, nH1);
  241.  
  242.   nY1 = YSIZ (44);            //  Directory List Y position
  243.   nH1 = YSIZ (38);            //  Directory List Box height
  244.   nY2 = YSIZ (84);            //  Files List Y position
  245.   nH2 = YSIZ (65);            //  Files List Box height
  246.   
  247.   hLbxLDir = CreateWindow (lpListBox, NULL, LBS_STYLE,          // Local Dir list
  248.     nX1, nY1, nExt, nH1, hParent, (HMENU) LST_LDIRS, hInst,  NULL);
  249.  
  250.   hLbxLFiles = CreateWindow (lpListBox, NULL, LBS_STYLE| LBS_EXTENDEDSEL,
  251.     nX1, nY2, nExt, nH2, hParent, (HMENU) LST_LFILES, hInst,  NULL);    // Local Files List
  252.  
  253.   hLbxRDir = CreateWindow(lpListBox, NULL, LBS_STYLE,           // Remote Dir List
  254.     nX2, nY1, nExt, nH1, hParent, (HMENU) LST_RDIRS, hInst,  NULL);
  255.  
  256.   hLbxRFiles = CreateWindow(lpListBox, NULL, LBS_STYLE| LBS_EXTENDEDSEL,
  257.     nX2, nY2, nExt, nH2, hParent, (HMENU) LST_RFILES, hInst,  NULL);    //  Remote Files List
  258.  
  259.   CreateListRectPos (&rcLDir,  nX1, nY1, nExt, nH1);
  260.   CreateListRectPos (&rcRDir,  nX2, nY1, nExt, nH1);
  261.   CreateListRectPos (&rcLFile, nX1, nY2, nExt, nH2);
  262.   CreateListRectPos (&rcRFile, nX2, nY2, nExt, nH2);
  263.  
  264.   CreateWindow (lpListBox, NULL, LBS_STANDARD|WS_CHILD,         // Temporary Files list
  265.     0, 0, nExt, nH1, hParent, (HMENU) LST_DELFILES, hInst,  NULL);
  266.  
  267.   SendDlgItemMessage (hParent, EDT_LFILETYPE, WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  268.   SendDlgItemMessage (hParent, EDT_RFILETYPE, WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  269.   SendDlgItemMessage (hParent, LST_LDIRLST,   WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  270.   SendDlgItemMessage (hParent, LST_RDIRLST,   WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  271.   SendDlgItemMessage (hParent, LST_LDIRS,     WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  272.   SendDlgItemMessage (hParent, LST_RDIRS,     WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  273.   SendDlgItemMessage (hParent, LST_LFILES,    WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  274.   SendDlgItemMessage (hParent, LST_RFILES,    WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  275.  
  276.   SendDlgItemMessage (hParent, LST_DELFILES,  WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG (TRUE, 0));
  277.  
  278.   SendDlgItemMessage (hParent, EDT_LFILETYPE, WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCSTR) szLFileType);
  279.   SendDlgItemMessage (hParent, EDT_RFILETYPE, WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCSTR) szRFileType);
  280.  
  281.   hTxtLDir   = CreateWindow (lpStatic, NULL, WS_TXTSTYLE, XSIZ (  9), YSIZ (21), XSIZ (100), YSIZ (8), hParent, (HMENU) TXT_LDIRECTORY, hInst,  NULL);
  282.   hTxtRDir   = CreateWindow (lpStatic, NULL, WS_TXTSTYLE, XSIZ (138), YSIZ (21), XSIZ (100), YSIZ (8), hParent, (HMENU) TXT_RDIRECTORY, hInst,  NULL);
  283.   hScroll    = CreateWindow (lpScroll, NULL, SBV_STYLE, XSIZ(230), YSIZ(164), XSIZ(8), YSIZ(15), hParent, (HMENU) SCRLWND, hInst, NULL);
  284.   
  285. #define WC_TEXT(style,x)   CreateWindow (lpStatic, NULL, WS_CHILDSTYLE | style, x, YSIZ(155), XSIZ(40), YSIZ(8), hParent, (HMENU) TXT_STATUS, hInst, NULL)
  286.  
  287.   hTxtLBytes = WC_TEXT (SS_RIGHT, (XSIZ(10)));
  288.   hTxtRBytes = WC_TEXT (SS_RIGHT, (XSIZ(198)));
  289.  
  290. #define WC_RADIO(Txt,x,ID) CreateWindow (lpButton, Txt, WS_RADIOSTYLE, x, YSIZ(154), XSIZ(39), YSIZ(9), hParent, (HMENU) ID, hInst, NULL)
  291.  
  292.   hRBascii = WC_RADIO ("ASCII",  (XSIZ ( 60)), RB_ASCII);
  293.   hRBbinary= WC_RADIO ("Binary", (XSIZ (115)), RB_BINARY);
  294.   hRBl8    = WC_RADIO ("L 8",    (XSIZ (160)), RB_L8);
  295.  
  296.   return(TRUE);
  297. }
  298.  
  299. HPEN hPenDark;
  300. HPEN hPenLight;
  301.  
  302. //*********************************************************************
  303. //  Draw a box to give the chiseled metal appearance
  304. //*********************************************************************
  305. void BoxIt (HDC hDC, int left, int top, int width, int height, BOOL flag)
  306. {
  307.   POINT Pt;
  308.   HPEN hPenOld;
  309.   
  310.   hPenOld = SelectObject (hDC, flag? hPenDark : hPenLight);
  311.   MoveToEx (hDC, (left*nWndx)/4, ((top+height)*nWndy)/8, &Pt);
  312.   LineTo (hDC, (left*nWndx)/4, (top*nWndy)/8);
  313.   LineTo (hDC, ((left+width)*nWndx)/4, (top*nWndy)/8);
  314.   if (flag) SelectObject (hDC,hPenLight); 
  315.   else SelectObject (hDC,hPenDark);
  316.   LineTo (hDC, ((left+width)*nWndx)/4, ((top+height)*nWndy)/8);
  317.   LineTo (hDC, (left*nWndx)/4, ((top+height)*nWndy)/8);
  318.   SelectObject (hDC, hPenOld);
  319. }
  320.  
  321. //*********************************************************************
  322. //*********************************************************************
  323. void BoxButton (HDC hDC, int left, int top, int width, int height, BOOL bFlag, BOOL bEnable)
  324. {
  325.   if (!bEnable)
  326.   {
  327.     HBRUSH hBr = GetStockObject (DKGRAY_BRUSH);
  328.     RECT rc;
  329.     
  330.     rc.top = YSIZ (top); rc.bottom = YSIZ (top+height);
  331.     rc.left = XSIZ (left); rc.right = XSIZ (left+width);
  332.     FillRect (hDC, &rc, hBr);
  333.   }
  334.   BoxIt (hDC, left, top, width, height, bFlag);
  335. }
  336.  
  337. //*********************************************************************
  338. //  Return the Button ID, given its index position
  339. //  Used for sending the WM_COMMAND message
  340. //*********************************************************************
  341. int GetButtonID (int nBtn)
  342. {
  343.   return bpButton[nBtn].nBtnID;
  344. }
  345.  
  346. //*********************************************************************
  347. //  Return the Button ID, given its index position
  348. //  Used for sending the WM_COMMAND message
  349. //*********************************************************************
  350. int GetButtonIndex (int nBtnID)
  351. {
  352.   int nI;
  353.   
  354.   for (nI=0; nI<sizeof (bpButton)/sizeof (BTNPOS); nI++)
  355.   {
  356.     if (bpButton[nI].nBtnID==nBtnID) return nI;
  357.   }
  358.   return -1;
  359. }
  360.  
  361. //*********************************************************************
  362. //  Return the Button SendMsg type - 0=>Post Message, 1=> SendMessage
  363. //*********************************************************************
  364. int GetButtonMsgStatus (int nBtn)
  365. {
  366.   return bpButton[nBtn].nSendMsg;
  367. }
  368.  
  369. //*********************************************************************
  370. //  Return the Button Status - 0=>Button is up, 1=> depressed
  371. //*********************************************************************
  372. int GetButtonStatus (int nBtn)
  373. {
  374.   return bpButton[nBtn].nStat;
  375. }
  376.  
  377. //*********************************************************************
  378. //  Set new button status, return the old one.
  379. //*********************************************************************
  380. int SetButtonStatus (int nBtn, int nStat)
  381. {
  382.   int nOld = bpButton[nBtn].nStat;
  383.   
  384.   bpButton[nBtn].nStat=nStat;  
  385.   return nOld;
  386. }
  387.  
  388. //*********************************************************************
  389. //  Return the Button Status - 0=>Button is up, 1=> depressed
  390. //*********************************************************************
  391. BOOL GetButtonEnabledStatus (int nBtn)
  392. {
  393.   return bEnabled[nBtn];
  394. }
  395.  
  396. //*********************************************************************
  397. //  Set Btn Enabled Status, Return Prev Status - True => Was Enabled
  398. //*********************************************************************
  399. BOOL SetButtonEnabledStatus (int nBtnID, BOOL bFlag)
  400. {
  401.   BOOL bFlagOld;
  402.   
  403.   nBtnID = GetButtonIndex (nBtnID);
  404.   if (nBtnID==-1) return FALSE;
  405.   bFlagOld = bEnabled[nBtnID];
  406.   bEnabled[nBtnID] = bFlag;
  407.   if (bFlag!=bFlagOld) InvalidateRect (hWndMain, &bpButton[nBtnID].rcBtn, TRUE);
  408.   return bFlagOld;
  409. }
  410.  
  411. //*********************************************************************
  412. //  Given x & y coords of a point, find which button it belongs to.
  413. //  Return index if found, else return -1
  414. //*********************************************************************
  415. int FindButtonClicked (int nXpos, int nYpos)
  416. {
  417.   int nI;
  418.   POINT pt;
  419.  
  420.   pt.x = nXpos;
  421.   pt.y = nYpos;
  422.   for (nI=0; nI<sizeof (bpButton)/sizeof (BTNPOS); nI++)
  423.   {
  424.     if (PtInRect (&bpButton[nI].rcBtn, pt)) return nI;
  425.   }
  426.   return -1;
  427. }
  428.  
  429. //*********************************************************************
  430. //  Enable all buttons
  431. //*********************************************************************
  432. void SetButtonsEnabled()
  433. {
  434.   int nI;
  435.  
  436.   for (nI=0; nI<BUTTONS; nI++) if (bEnabled[nI]!=TRUE) InvalidateRect (hWndMain, &bpButton[nI].rcBtn, TRUE);
  437.   for (nI=0; nI<BUTTONS; nI++) bEnabled[nI] = TRUE;
  438. }
  439.  
  440. //*********************************************************************
  441. //  Reduce the RECT size by n Pixels along all dimensions
  442. //*********************************************************************
  443. RECT ReduceRect (RECT rc, int nPix)
  444. {
  445.   nPix >>= 1;
  446.   rc.left   += nPix;
  447.   rc.right  -= nPix;
  448.   rc.top    += nPix;
  449.   rc.bottom -= nPix;
  450.   return rc;
  451. }
  452.  
  453. //*********************************************************************
  454. //*********************************************************************
  455. void CreateButtonPens()
  456. {
  457.   hPenDark  = CreatePen (PS_SOLID, 1, RGB (128,128,128));
  458.   hPenLight = CreatePen (PS_SOLID, 1, RGB (224,224,224));
  459. }
  460.  
  461. //*********************************************************************
  462. //*********************************************************************
  463. void DeleteButtonPens()
  464. {
  465.   DeleteObject (hPenDark);
  466.   DeleteObject (hPenLight);
  467. }
  468.  
  469. //*********************************************************************
  470. //  Paint a single button, with the status supplied - up/down.  Button
  471. //  specified by its index number.
  472. //*********************************************************************
  473. int DoPaintButton (HWND hWnd, int nBtn, int nStat)
  474. {
  475.   RECT  rc   = bpButton[nBtn].rcExt;
  476.   LPSTR lpsz = *bpButton[nBtn].lpBtnTxt;
  477.   int   nX   = bpButton[nBtn].nTxtx + nStat;
  478.   int   nY   = bpButton[nBtn].nTxty + nStat;
  479.   
  480.   HBRUSH hBrushOld;
  481.   HBRUSH hBrush=CreateSolidBrush (RGB(192,192,192));
  482.   HDC hDC = GetDC (hWnd);
  483.  
  484.   //*************************************************
  485.   // Create two temporary pens to do the 3-D effect
  486.   //*************************************************
  487.   CreateButtonPens();
  488.  
  489.   //*************************************************
  490.   //  Prepare the hdc for drawing the button
  491.   //*************************************************
  492.   hBrushOld = SelectObject (hDC, hBrush);
  493.   SelectObject (hDC, GetStockObject (ANSI_VAR_FONT));
  494.   SetBkColor (hDC, RGB (192, 192, 192));
  495.  
  496.   //*************************************************
  497.   //  Draw the bounding box as 3-D, then fill inside
  498.   //  with Gray brush, lastly draw the text
  499.   //*************************************************
  500.   BoxIt (hDC, rc.left, rc.top, rc.right, rc.bottom, nStat?TRUE:FALSE);
  501.   rc = ReduceRect (bpButton[nBtn].rcBtn, 6);
  502.   FillRect (hDC, &rc, bEnabled[nBtn]? hBrush : GetStockObject (DKGRAY_BRUSH));
  503.   if (bEnabled[nBtn]) TextOut (hDC, nX, nY, (LPSTR) lpsz, lstrlen (lpsz));
  504.   
  505.   //*************************************************
  506.   // Release the pens and brushes created this run.
  507.   //*************************************************
  508.   SelectObject (hDC, GetStockObject (BLACK_PEN));
  509.   DeleteObject (SelectObject (hDC, hBrushOld));
  510.   DeleteButtonPens();
  511.   
  512.   //*************************************************
  513.   //  Final cleanup
  514.   //*************************************************
  515.   ReleaseDC (hWnd, hDC);
  516.   return 0;
  517. }
  518.  
  519. //*********************************************************************
  520. //*********************************************************************
  521. DoMainPaint(HWND hWnd)
  522. {
  523.   HDC         hDC;   // handle for the display device
  524.   PAINTSTRUCT ps;    // holds PAINT information
  525.   HBRUSH      hBrush, hBrushOld, hDkBrush;
  526.   int         nI;
  527.  
  528.   memset (&ps, 0x00, sizeof(PAINTSTRUCT));
  529.   hDC = BeginPaint (hWnd, &ps);
  530.  
  531.   hBrush = CreateSolidBrush (RGB(192,192,192));
  532.   hPenDark = CreatePen (PS_SOLID,1,RGB(128,128,128));
  533.   hPenLight = CreatePen (PS_SOLID,1,RGB(224,224,224));
  534.  
  535.   hBrushOld = SelectObject (hDC, hBrush);            // Save original handle
  536.   SelectObject (hDC, GetStockObject (ANSI_VAR_FONT));   // Prepare Device Context
  537.   SetBkColor (hDC, RGB (192,192,192));
  538.  
  539.   BoxIt (hDC,   4,2,109,149,TRUE);            //  Locals 3-D box
  540.   BoxIt (hDC, 133,2,109,149,TRUE);            //  Remotes 3-D box
  541.  
  542.   BoxIt (hDC,   7,5,103,12,TRUE);             //  "Local" window 
  543.   BoxIt (hDC, 136,5,103,12,TRUE);             //  "Remote" window
  544.  
  545.   BoxIt (hDC,  4,153,238,29,TRUE);            //  Outer 3-D Grouping Box
  546.   BoxIt (hDC,  7,163,232,17,FALSE);           //  Inner 3-D FTP Message box
  547.   
  548.   BoxIt (hDC,  7,19,103,10,FALSE);            //  Local 3-D Current Dir box
  549.   BoxIt (hDC,136,19,103,10,FALSE);            //  Remote 3-D Current Dir box
  550.  
  551.   TextOut (hDC, XSIZ (  9), YSIZ (8),"Local PC info",13);
  552.   TextOut (hDC, XSIZ (138), YSIZ (8),"Remote host info",16);
  553.  
  554.   //*************************************************
  555.   //  Now draw the 3-D effects for all the buttons
  556.   //  and print the text for each button.
  557.   //*************************************************
  558.   
  559.   FillRect (hDC, &rcMsg, hBrush);
  560.   if (lpStatusLines!=NULL)
  561.   {
  562.     char *lp;
  563.     HRGN hRgn;
  564.     
  565.     hRgn = CreateRectRgn (rcMsg.left, rcMsg.top, rcMsg.right, rcMsg.bottom);
  566.     SelectClipRgn (hDC, hRgn);
  567.     lp = lpStatusLines+(nStatusScroll*STATLEN);
  568.     TextOut (hDC, XSIZ(9), YSIZ(172), lp, lstrlen (lp));
  569.     if (nStatusScroll>0)
  570.     {
  571.       lp = lpStatusLines+((nStatusScroll-1)*STATLEN);
  572.       TextOut (hDC, XSIZ(9), YSIZ(165), lp, lstrlen (lp));
  573.     }
  574.     SelectClipRgn (hDC, (HRGN) NULL);
  575.     DeleteObject (hRgn);
  576.   }
  577.  
  578.   hDkBrush = GetStockObject (DKGRAY_BRUSH);
  579.   SetBkMode (hDC, TRANSPARENT);
  580.   for (nI=0; nI<sizeof (bpButton)/sizeof (BTNPOS); nI++)
  581.   {
  582.     LPSTR lpsz = *bpButton[nI].lpBtnTxt;
  583.     RECT  rc   =  bpButton[nI].rcExt;
  584.     int   nX   =  bpButton[nI].nTxtx + bpButton[nI].nStat;
  585.     int   nY   =  bpButton[nI].nTxty + bpButton[nI].nStat;
  586.  
  587.     BoxIt (hDC, rc.left, rc.top, rc.right, rc.bottom, bpButton[nI].nStat?TRUE:FALSE);
  588.     rc = ReduceRect (bpButton[nI].rcBtn, 6);
  589.     FillRect (hDC, &rc, bEnabled[nI]? hBrush : hDkBrush);
  590.     if (bEnabled[nI]) TextOut (hDC, nX, nY, (LPSTR) lpsz, lstrlen (lpsz));
  591.   }
  592.  
  593.   SelectObject (hDC, hBrushOld);         //  Deselect any created resources
  594.   SelectObject (hDC, GetStockObject (BLACK_PEN));
  595.   
  596. // Inform Windows painting is complete
  597.   EndPaint (hWnd, &ps);
  598.   DeleteObject (hBrush);              //  Release all resources created
  599.   DeleteObject (hPenLight);
  600.   DeleteObject (hPenDark);  
  601.   return 0;
  602. }
  603.  
  604. //*********************************************************************
  605. //*********************************************************************
  606.  
  607. #ifdef WIN32
  608.  
  609. int GetLocalDirForWnd(HWND hWnd)
  610. {
  611.   WIN32_FIND_DATA ffblk;
  612.   HANDLE hFile;
  613.  
  614.   // get the local directory name
  615.   // DLG_LDIRECTORY (directory name)
  616.   getcwd (szString,180);
  617.   SendMessage (hTxtLDir,WM_SETTEXT,0,(LPARAM)(LPCSTR) szString);
  618.   SendDlgItemMessage (hWnd, LST_LDIRLST, CB_SELECTSTRING, (WPARAM) 0, (LPARAM)(LPCSTR) szString);
  619.  
  620.   // DLG_LDIRS      (directory list box)
  621.   SendMessage (hLbxLDir,LB_RESETCONTENT,0,0);
  622.  
  623.   if ((hFile = FindFirstFile ("*.*", &ffblk))!=INVALID_HANDLE_VALUE)
  624.   {
  625.     do 
  626.     {
  627.       if ((ffblk.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  628.           (lstrcmp (ffblk.cFileName, ".")!=0))
  629.              SendMessage (hLbxLDir,LB_ADDSTRING,0,(LPARAM)(LPCSTR) ffblk.cFileName);
  630.     }
  631.     while (FindNextFile (hFile, &ffblk));
  632.     FindClose (hFile);
  633.   }
  634.  
  635.   // add drives to the list box
  636.   SendMessage(hLbxLDir, LB_DIR, 0x4000 | 0x8000, (LPARAM) ((LPSTR) "*"));
  637.  
  638.   // DLG_LFILES     (file list box)
  639.   SendMessage (hLbxLFiles, LB_RESETCONTENT, 0, 0);
  640.  
  641.   SendDlgItemMessage (hWndMain, EDT_LFILETYPE, WM_GETTEXT, (WPARAM) sizeof (szLFileType), (LPARAM)(LPCSTR) szLFileType);
  642.   if (lstrlen (szLFileType)==0) 
  643.   {
  644.     lstrcpy (szLFileType, "*.*");
  645.     SendDlgItemMessage (hWndMain, EDT_LFILETYPE, WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCSTR) szLFileType);
  646.   }
  647.   
  648.   if ((hFile = FindFirstFile (szLFileType, &ffblk))!=INVALID_HANDLE_VALUE)
  649.   {
  650.     do 
  651.     {
  652.       if (!(ffblk.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  653.              SendMessage (hLbxLFiles, LB_ADDSTRING, 0, (LPARAM)(LPCSTR) ffblk.cFileName);
  654.     }
  655.     while (FindNextFile (hFile, &ffblk));
  656.     FindClose (hFile);
  657.   }
  658.   
  659.   return 0;
  660. }
  661.  
  662. #else
  663.  
  664. int GetLocalDirForWnd(HWND hWnd)
  665. {
  666.  
  667. #ifdef _BORLANDC_
  668.   struct ffblk ffblk;
  669. #else
  670.   #define ff_attrib attrib
  671.   #define ff_name name
  672.   #define findnext(a) _dos_findnext(a)
  673.   struct _find_t ffblk;
  674. #endif  
  675.   
  676.   int nDone;
  677.  
  678.   // get the local directory name
  679.   // DLG_LDIRECTORY (directory name)
  680.   getcwd (szString,180);
  681.   SendMessage (hTxtLDir,WM_SETTEXT,0,(LPARAM)(LPCSTR) szString);
  682.   SendDlgItemMessage (hWnd, LST_LDIRLST, CB_SELECTSTRING, (WPARAM) 0, (LPARAM)(LPCSTR) szString);
  683.   // DLG_LDIRS      (directory list box)
  684.   SendMessage (hLbxLDir,LB_RESETCONTENT,0,0);
  685.  
  686. #ifdef _BORLANDC_
  687.   nDone = findfirst("*.*",&ffblk,FA_DIREC);
  688. #else
  689.   nDone=_dos_findfirst("*.*",_A_SUBDIR,&ffblk);
  690. #endif  
  691.  
  692.   while (!nDone)
  693.   {
  694.     if (ffblk.ff_attrib & 0x10 && lstrcmp(ffblk.ff_name,".")!=0)
  695.       SendMessage (hLbxLDir, LB_ADDSTRING, 0, (LPARAM)(LPCSTR) ffblk.ff_name);
  696.     nDone = findnext (&ffblk);
  697.   }
  698.   // add drives to the list box
  699.   SendMessage (hLbxLDir, LB_DIR, 0x4000 | 0x8000, (LPARAM) ((LPSTR) "*"));
  700.  
  701.   // DLG_LFILES     (file list box)
  702.   SendMessage (hLbxLFiles, LB_RESETCONTENT, 0, 0);
  703.  
  704.   SendDlgItemMessage (hWndMain, EDT_LFILETYPE, WM_GETTEXT, (WPARAM) sizeof (szLFileType), (LPARAM)(LPCSTR) szLFileType);
  705.   if (lstrlen (szLFileType)==0) 
  706.   {
  707.     lstrcpy (szLFileType, "*.*");
  708.     SendDlgItemMessage (hWndMain, EDT_LFILETYPE, WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCSTR) szLFileType);
  709.   }
  710.   
  711. #ifdef _BORLANDC_
  712.   nDone = findfirst (szLFileType, &ffblk, 0);
  713. #else
  714.   nDone=_dos_findfirst (szLFileType, _A_NORMAL, &ffblk);
  715. #endif
  716.   
  717.   while (!nDone)  
  718.   {
  719.     if (!(ffblk.ff_attrib & 0x10)) 
  720.     {
  721.       lstrcpy (szString,ffblk.ff_name);
  722.       strlwr (szString);
  723.       SendMessage (hLbxLFiles, LB_ADDSTRING, 0, (LPARAM)(LPCSTR) szString);
  724.     }
  725.     nDone = findnext (&ffblk);
  726.   }
  727.   return 0;
  728. }
  729.  
  730. #endif
  731.  
  732. //*********************************************************************
  733. // Return a Status Line Pointer
  734. //*********************************************************************
  735. LPSTR GetStatusLine (int nLine)
  736. {
  737.   if (lpStatusLines==NULL) return NULL;
  738.   return (LPSTR) (lpStatusLines + nLine*STATLEN);
  739. }
  740.  
  741. //*********************************************************************
  742. //*********************************************************************
  743. int GetMaxStatusLines()
  744. {
  745.   return __min (nStatusPtr, MAXLINES);
  746. }
  747.  
  748. //*********************************************************************
  749. //  Display the Scroll Message
  750. //*********************************************************************
  751. ScrollStatus (HWND hWnd, int value) 
  752. {
  753.   int nNew=nStatusScroll+value;
  754.   
  755.   nNew = __min (__max (nNew, 1), nStatusPtr);
  756.   if (nNew!=nStatusScroll)
  757.   {
  758.     nStatusScroll = nNew;
  759.     InvalidateRect (hWnd, &rcMsg, FALSE);
  760.   }
  761.   return 0;
  762. }
  763.  
  764. //*********************************************************************
  765. //*********************************************************************
  766. SetStatus (HWND hWnd, LPSTR lpString) 
  767. {
  768.   if (lpStatusLines==NULL)
  769.   {
  770.     (char *) lpStatusLines = (char *) GlobalAllocPtr (GHND, (MAXLINES+1) * STATLEN);
  771.     nStatusPtr = 0;
  772.     if (lpStatusLines==NULL) return 0;
  773.   }
  774.   
  775.   if (nStatusPtr>(MAXLINES-1))
  776.     memmove (lpStatusLines, lpStatusLines+STATLEN, (MAXLINES*STATLEN));
  777.  
  778.   if (lstrlen (lpString) > (STATLEN-1)) lpString[STATLEN-1] = '\0';
  779.   lstrcpy (lpStatusLines+nStatusPtr*STATLEN, lpString);
  780.   nStatusScroll = nStatusPtr;
  781.   if (nStatusPtr<MAXLINES) nStatusPtr++;
  782.   InvalidateRect (hWnd, &rcMsg, FALSE);
  783.   return 0;
  784. }
  785.  
  786. //*********************************************************************
  787. //*********************************************************************
  788. UnsetStatusLines()
  789. {
  790.   if (lpStatusLines!=NULL) GlobalFreePtr (lpStatusLines), lpStatusLines=NULL;  
  791.   return 0;
  792. }
  793.  
  794.  
  795.